package io.github.frailty9.crserver.dso.service.impl;

import com.mybatisflex.core.paginate.Page
import com.mybatisflex.kotlin.extensions.db.insert
import com.mybatisflex.kotlin.extensions.db.paginate
import com.mybatisflex.kotlin.extensions.db.query
import com.mybatisflex.kotlin.extensions.db.queryOne
import com.mybatisflex.kotlin.extensions.kproperty.eq
import com.mybatisflex.kotlin.extensions.kproperty.ge
import com.mybatisflex.kotlin.extensions.kproperty.le
import com.mybatisflex.kotlin.extensions.wrapper.whereWith
import io.github.frailty9.crserver.dso.service.ResourceInstanceService
import io.github.frailty9.crserver.model.Resource;
import io.github.frailty9.crserver.dso.service.ResourceService;
import io.github.frailty9.crserver.dto.ResourcePublishDto
import io.github.frailty9.crserver.model.ResourceInstanceTemplate
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject
import org.noear.solon.data.annotation.Transaction
import java.time.LocalDate

/**
 * ResourceServiceImpl
 */
@Component
open class ResourceServiceImpl : ResourceService {

    @Inject
    private lateinit var resourceInstanceService: ResourceInstanceService

    @Transaction
    override fun publish(uid: Long, resourcePublishDto: ResourcePublishDto) {

        val resource = resourcePublishDto.toResource(uid)
//        this.save(resource)
        insert(resource)

        val rid = resource.id!!
        // 创建资源模板
        for (ritDto in resourcePublishDto.repeatRules) {
            val rit = ResourceInstanceTemplate(
                resourceId = rid,
                startTime = ritDto.startTime,
                endTime = ritDto.endTime,
                capacityUnits = ritDto.capacityUnits,
                daysOfWeek = ritDto.daysOfWeek,
                daysOfMonth = ritDto.daysOfMonth
            )
//            resourceTemplateService.save(rit)
            insert(rit)
        }
        resourceInstanceService.generateInstancesForResource(rid, 7)
    }

    /**
     * 查询在指定日期前结束的活跃资源（用于实例生成）
     */
    @Transaction(readOnly = true)
    override fun findResourcesActiveBefore(endDate: LocalDate): List<Long> {
        return query<Resource> {
            select(Resource::id)
            Resource::effectiveEnd le endDate
        }.map { it.id!! }
    }

    @Transaction(readOnly = true)
    override fun getActiveResourceDtoPage(current: Number, size: Number): Page<Resource> {
        val page = paginate<Resource>(current, size) {
            whereWith {
                Resource::status eq 1
                Resource::effectiveStart le LocalDate.now()
                Resource::effectiveEnd ge LocalDate.now()
            }
        }
        return page
    }

    @Transaction(readOnly = true)
    override fun getById(id: Long): Resource? {
        return queryOne<Resource> {
            whereWith {
                Resource::id eq id
            }
        }
    }
}
